from django.conf import settings
from django.shortcuts import render, redirect, get_object_or_404, reverse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.core.mail import send_mail
from django.utils import timezone
from django.http import JsonResponse
from django.db.models import Q
from datetime import timedelta
import random
import string
import re
from django.core.cache import cache
import redis

from social.models import Follow
from .forms import AvatarUpdateForm
from .models import User, PasswordResetCode
from activities.models import Activity, ActivityRegistration


def register(request):
    """用户注册视图 - 需要邮箱验证码"""
    if request.method == 'POST':
        username = request.POST.get('username')
        email = request.POST.get('email')
        phone = request.POST.get('phone', '').strip()  # 去除空格
        password = request.POST.get('password')
        password_confirm = request.POST.get('password_confirm')
        verify_code = request.POST.get('verify_code')

        # 将空字符串转换为 None，避免 unique 约束冲突
        if not phone:
            phone = None

        # 验证逻辑
        if password != password_confirm:
            messages.error(request, '两次密码输入不一致')
            return render(request, 'users/register.html')
        if User.objects.filter(username=username).exists():
            messages.error(request, '用户名已存在')
            return render(request, 'users/register.html')
        if User.objects.filter(email=email).exists():
            messages.error(request, '邮箱已被注册')
            return render(request, 'users/register.html')
        if phone and User.objects.filter(phone=phone).exists():
            messages.error(request, '手机号已被注册')
            return render(request, 'users/register.html')

        # 验证邮箱验证码
        redis_client = redis.Redis(
            host=settings.REDIS_CONFIG['host'],
            port=settings.REDIS_CONFIG['port'],
            password=settings.REDIS_CONFIG['password'],
            db=settings.REDIS_CONFIG['db'],
            decode_responses=True
        )
        stored_code = redis_client.get(f'register_code:{email}')
        if not stored_code or stored_code != verify_code:
            messages.error(request, '验证码无效或已过期')
            return render(request, 'users/register.html')

        # 创建用户
        User.objects.create_user(
            username=username,
            email=email,
            password=password,
            phone=phone
        )
        
        # 删除已使用的验证码
        redis_client.delete(f'register_code:{email}')
        
        messages.success(request, '注册成功，请登录')
        return redirect('users:login')

    return render(request, 'users/register.html')


# def user_login(request):
#     """用户登录视图"""
#     if request.method == 'POST':
#         username = request.POST.get('username')
#         password = request.POST.get('password')
#         user = authenticate(request, username=username, password=password)

#         if user:
#             login(request, user)
#             messages.success(request, f'欢迎回来，{user.nickname or user.username}！')
#             return redirect(request.GET.get('next', '/'))
#         else:
#             messages.error(request, '用户名或密码错误')

#     return render(request, 'users/login.html')


#自定义登录视图
# def custom_login(request):
#     """用户登录视图 - 支持管理员跳转和邮箱验证码登录"""
#     if request.method == 'POST':
#         login_type = request.POST.get('login_type', 'password')  # password or code
#
#         if login_type == 'code':
#             # 邮箱验证码登录
#             email = request.POST.get('email')
#             verify_code = request.POST.get('verify_code')
#
#             # 验证邮箱验证码
#             redis_client = redis.Redis(
#                 host=settings.REDIS_CONFIG['host'],
#                 port=settings.REDIS_CONFIG['port'],
#                 password=settings.REDIS_CONFIG['password'],
#                 db=settings.REDIS_CONFIG['db'],
#                 decode_responses=True
#             )
#             stored_code = redis_client.get(f'login_code:{email}')
#
#             if not stored_code or stored_code != verify_code:
#                 messages.error(request, '验证码无效或已过期')
#                 return render(request, 'users/login.html')
#
#             # 查找用户
#             try:
#                 user = User.objects.get(email=email)
#                 login(request, user, backend='django.contrib.auth.backends.ModelBackend')
#
#                 # 删除已使用的验证码
#                 redis_client.delete(f'login_code:{email}')
#
#                 # messages.success(request, f'欢迎回来，{user.nickname or user.username}！')
#
#                 # 超级管理员跳转到后台
#                 if user.is_superuser:
#                     return redirect(settings.ADMIN_LOGIN_REDIRECT_URL)
#
#                 # 普通用户：检查是否有next参数
#                 next_url = request.POST.get('next') or request.GET.get('next')
#                 if next_url:
#                     return redirect(next_url)
#
#                 # 默认跳转到首页
#                 return redirect(settings.LOGIN_REDIRECT_URL)
#             except User.DoesNotExist:
#                 messages.error(request, '该邮箱未注册')
#                 return render(request, 'users/login.html')
#         else:
#             # 密码登录
#             username = request.POST.get('username')
#             password = request.POST.get('password')
#             user = authenticate(request, username=username, password=password)
#
#             if user is not None:
#                 login(request, user)
#                 # messages.success(request, f'欢迎回来，{user.nickname or user.username}！')
#
#                 # 超级管理员跳转到后台
#                 if user.is_superuser:
#                     return redirect(settings.ADMIN_LOGIN_REDIRECT_URL)
#
#                 # 普通用户：检查是否有next参数
#                 next_url = request.POST.get('next') or request.GET.get('next')
#                 if next_url:
#                     return redirect(next_url)
#
#                 # 默认跳转到首页
#                 return redirect(settings.LOGIN_REDIRECT_URL)
#             else:
#                 messages.error(request, '用户名或密码错误')
#
#     return render(request, 'users/login.html')
def custom_login(request):
    """用户登录视图 - 支持管理员跳转和邮箱验证码登录"""
    if request.method == 'POST':
        login_type = request.POST.get('login_type', 'password')  # password or code

        if login_type == 'code':
            # 邮箱验证码登录（保持不变）
            email = request.POST.get('email')
            verify_code = request.POST.get('verify_code')

            # 验证邮箱验证码
            redis_client = redis.Redis(
                host=settings.REDIS_CONFIG['host'],
                port=settings.REDIS_CONFIG['port'],
                password=settings.REDIS_CONFIG['password'],
                db=settings.REDIS_CONFIG['db'],
                decode_responses=True
            )
            stored_code = redis_client.get(f'login_code:{email}')

            if not stored_code or stored_code != verify_code:
                messages.error(request, '验证码无效或已过期')
                return render(request, 'users/login.html')

            # 查找用户
            try:
                user = User.objects.get(email=email)
                login(request, user, backend='django.contrib.auth.backends.ModelBackend')

                # 删除已使用的验证码
                redis_client.delete(f'login_code:{email}')

                # 超级管理员跳转到后台
                if user.is_superuser:
                    return redirect(settings.ADMIN_LOGIN_REDIRECT_URL)

                # 普通用户：检查是否有next参数
                next_url = request.POST.get('next') or request.GET.get('next')
                if next_url:
                    return redirect(next_url)

                # 默认跳转到首页
                return redirect(settings.LOGIN_REDIRECT_URL)
            except User.DoesNotExist:
                messages.error(request, '该邮箱未注册')
                return render(request, 'users/login.html')
        else:
            # 密码登录（修改此处，支持邮箱登录）
            username_or_email = request.POST.get('username')  # 可能是用户名或邮箱
            password = request.POST.get('password')

            # 步骤1：判断输入的是邮箱还是用户名（通过正则匹配）
            import re
            email_pattern = r'^[^\s@]+@[^\s@]+\.[^\s@]+$'
            user = None

            if re.match(email_pattern, username_or_email):
                # 若输入的是邮箱，通过邮箱查询用户
                try:
                    user = User.objects.get(email=username_or_email)
                except User.DoesNotExist:
                    messages.error(request, '用户名或密码错误')  # 统一错误提示，避免信息泄露
                    return render(request, 'users/login.html')
            else:
                # 若输入的是用户名，通过用户名查询用户
                try:
                    user = User.objects.get(username=username_or_email)
                except User.DoesNotExist:
                    messages.error(request, '用户名或密码错误')
                    return render(request, 'users/login.html')

            # 步骤2：验证用户密码是否正确
            if user.check_password(password):
                # 密码正确，登录用户
                login(request, user, backend='django.contrib.auth.backends.ModelBackend')

                # 超级管理员跳转到后台
                if user.is_superuser:
                    return redirect(settings.ADMIN_LOGIN_REDIRECT_URL)

                # 普通用户：检查next参数
                next_url = request.POST.get('next') or request.GET.get('next')
                if next_url:
                    return redirect(next_url)

                # 默认跳转到首页
                return redirect(settings.LOGIN_REDIRECT_URL)
            else:
                # 密码错误
                messages.error(request, '用户名或密码错误')

    return render(request, 'users/login.html')

@login_required
def user_logout(request):
    """用户登出视图"""
    logout(request)
    return redirect('home')


def password_reset(request):
    """渲染密码重置页面（合并步骤）"""
    return render(request, 'users/password_reset.html')


def send_verify_code(request):
    """发送验证码的AJAX接口 - 支持登录、注册、密码重置"""
    if request.method != 'POST':
        return JsonResponse({'success': False, 'msg': '仅支持POST请求'})

    email = request.POST.get('email', '').strip()
    code_type = request.POST.get('type', 'reset')  # login, register, reset
    
    if not re.match(r'^[^\s@]+@[^\s@]+\.[^\s@]+$', email):
        return JsonResponse({
            'success': False,
            'msg': '请输入有效的邮箱地址'
        })

    # 根据类型验证邮箱
    if code_type == 'reset' or code_type == 'login':
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            return JsonResponse({
                'success': False,
                'msg': '该邮箱未注册'
            })
    elif code_type == 'register':
        if User.objects.filter(email=email).exists():
            return JsonResponse({
                'success': False,
                'msg': '该邮箱已被注册'
            })

    # 连接Redis
    redis_client = redis.Redis(
        host=settings.REDIS_CONFIG['host'],
        port=settings.REDIS_CONFIG['port'],
        password=settings.REDIS_CONFIG['password'],
        db=settings.REDIS_CONFIG['db'],
        decode_responses=True
    )
    
    # 检查1分钟内是否已发送过验证码（防刷）
    rate_limit_key = f'{code_type}_code_rate:{email}'
    if redis_client.exists(rate_limit_key):
        return JsonResponse({
            'success': False,
            'msg': '验证码已发送，1分钟内请勿重复请求'
        })

    # 生成验证码
    verify_code = ''.join(random.choices(string.digits, k=6))
    
    # 存储到Redis，5分钟有效期
    redis_key = f'{code_type}_code:{email}'
    redis_client.setex(redis_key, 300, verify_code)  # 300秒 = 5分钟
    
    # 设置1分钟的发送频率限制
    redis_client.setex(rate_limit_key, 60, '1')

    # 发送邮件
    subject_map = {
        'login': '活动聚 - 登录验证码',
        'register': '活动聚 - 注册验证码',
        'reset': '活动聚 - 密码重置验证码'
    }
    
    try:
        send_mail(
            subject=subject_map.get(code_type, '活动聚 - 验证码'),
            message=f'您的验证码是：{verify_code}，有效期5分钟。请勿向他人泄露。',
            from_email=settings.EMAIL_HOST_USER,
            recipient_list=[email],
            fail_silently=False
        )
        return JsonResponse({'success': True, 'msg': '验证码已发送'})
    except Exception as e:
        return JsonResponse({
            'success': False,
            'msg': f'发送失败：{str(e)[:50]}'
        })


def reset_password(request):
    """重置密码的AJAX接口 - 使用Redis验证码"""
    if request.method != 'POST':
        return JsonResponse({
            'success': False,
            'msg': '仅支持POST请求',
            'type': 'system'
        })

    email = request.POST.get('email', '').strip()
    verify_code = request.POST.get('verify_code', '').strip()
    new_password = request.POST.get('new_password', '').strip()
    confirm_password = request.POST.get('confirm_password', '').strip()

    # 邮箱验证
    if not re.match(r'^[^\s@]+@[^\s@]+\.[^\s@]+$', email):
        return JsonResponse({
            'success': False,
            'msg': '请输入有效的邮箱地址',
            'type': 'email'
        })

    # 验证用户是否存在
    try:
        user = User.objects.get(email=email)
    except User.DoesNotExist:
        return JsonResponse({
            'success': False,
            'msg': '该邮箱未注册',
            'type': 'email'
        })

    # 连接Redis验证验证码
    redis_client = redis.Redis(
        host=settings.REDIS_CONFIG['host'],
        port=settings.REDIS_CONFIG['port'],
        password=settings.REDIS_CONFIG['password'],
        db=settings.REDIS_CONFIG['db'],
        decode_responses=True
    )
    
    stored_code = redis_client.get(f'reset_code:{email}')
    if not stored_code or stored_code != verify_code:
        return JsonResponse({
            'success': False,
            'msg': '验证码无效或已过期',
            'type': 'code'
        })

    # 密码验证
    if len(new_password) < 6:
        return JsonResponse({
            'success': False,
            'msg': '新密码至少6位',
            'type': 'pwd'
        })
    
    if new_password != confirm_password:
        return JsonResponse({
            'success': False,
            'msg': '两次密码输入不一致',
            'type': 'pwd'
        })

    # 执行密码重置
    user.set_password(new_password)
    user.save()

    # 删除已使用的验证码
    redis_client.delete(f'reset_code:{email}')

    return JsonResponse({'success': True, 'msg': '密码重置成功'})


@login_required
def profile(request):
    """用户个人资料视图"""
    user = request.user
    created_activities = Activity.objects.filter(creator=user)
    registrations = ActivityRegistration.objects.filter(user=user, status='registered')
    interests_list = user.interests.split() if user.interests else []

    context = {
        'user': user,
        'created_activities': created_activities,
        'registrations': registrations,
        'interests_list': interests_list,
    }
    return render(request, 'users/profile.html', context)


@login_required
def profile_edit(request):
    """编辑用户资料视图"""
    # 确保 Cloudinary 配置加载
    from django.conf import settings
    import cloudinary

    # 手动配置 Cloudinary（确保在文件操作前配置）
    cloudinary.config(
        cloud_name=settings.CLOUDINARY_STORAGE['CLOUD_NAME'],
        api_key=settings.CLOUDINARY_STORAGE['API_KEY'],
        api_secret=settings.CLOUDINARY_STORAGE['API_SECRET'],
        secure=True
    )
    if request.method == 'POST':
        user = request.user
        user.nickname = request.POST.get('nickname', '')
        user.signature = request.POST.get('signature', '')
        user.interests = request.POST.get('interests', '')
        user.show_phone = request.POST.get('show_phone') == 'on'
        user.show_email = request.POST.get('show_email') == 'on'
        user.show_activities = request.POST.get('show_activities') == 'on'

        if 'avatar' in request.FILES:
            user.avatar = request.FILES['avatar']

        user.save()
        messages.success(request, '资料更新成功')
        return redirect('users:profile')

    return render(request, 'users/profile_edit.html')


def user_profile(request, user_id):
    """查看其他用户资料视图"""
    profile_user = get_object_or_404(User, id=user_id)

    # 修复：将 user 改为 profile_user
    created_activities = Activity.objects.filter(creator=profile_user, status='approved') \
        if (profile_user.show_activities or request.user == profile_user) else None

    # 添加关注状态检查
    is_following = False
    if request.user.is_authenticated and request.user != profile_user:
        is_following = Follow.objects.filter(
            follower=request.user,
            following=profile_user
        ).exists()

    context = {
        'profile_user': profile_user,
        'created_activities': created_activities,
        'is_following': is_following,
    }
    return render(request, 'users/user_profile.html', context)


@login_required
def my_activities(request):
    """用户创建的活动列表视图"""
    activities = Activity.objects.filter(creator=request.user).order_by('-created_at')
    return render(request, 'users/my_activities.html', {'activities': activities})


@login_required
def my_registrations(request):
    """用户报名的活动列表视图"""
    registrations = ActivityRegistration.objects.filter(
        user=request.user,
        status='registered'
    ).select_related('activity').order_by('-created_at')
    return render(request, 'users/my_registrations.html', {'registrations': registrations})



# 头像管理视图
@login_required
def update_avatar(request):
    """更新用户头像"""
    if request.method == 'POST':
        form = AvatarUpdateForm(request.POST, request.FILES, instance=request.user)
        if form.is_valid():
            form.save()
            messages.success(request, '头像更新成功！')
            return redirect('users:profile')
        else:
            messages.error(request, '头像更新失败，请检查文件格式和大小')
    else:
        form = AvatarUpdateForm(instance=request.user)

    return render(request, 'users/update_avatar.html', {'form': form})


@login_required
def delete_avatar(request):
    """删除用户头像"""
    if request.method == 'POST':
        user = request.user
        if user.avatar:
            # 删除 Cloudinary 上的文件
            user.avatar.delete()
            user.avatar = None
            user.save()
            messages.success(request, '头像删除成功！')
        else:
            messages.info(request, '您还没有设置头像')
        return redirect('users:profile')

    # 如果不是POST请求，重定向到个人资料页
    return redirect('users:profile')


# 在 views.py 中添加以下视图函数

@login_required
def my_following(request):
    """我关注的用户列表"""
    following = Follow.objects.filter(follower=request.user).select_related('following')
    return render(request, 'users/my_following.html', {'following': following})

@login_required
def my_followers(request):
    """关注我的用户列表"""
    followers = Follow.objects.filter(following=request.user).select_related('follower')
    return render(request, 'users/my_followers.html', {'followers': followers})